home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Reference Guide
/
C-C++ Interactive Reference Guide.iso
/
c_ref
/
csource5
/
357_01
/
cstar1.exe
/
ST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-18
|
9KB
|
448 lines
/*
C* -- symbol table routines.
source: st.c
started: November 4, 1985
version:
December 24, 1986
March 7, 1989
PUBLIC DOMAIN SOFTWARE
The CSTAR program was placed in the public domain on June 15, 1991,
by its author and sole owner,
Edward K. Ream
1617 Monroe Street
Madison, WI 53711
(608) 257-0802
CSTAR may be used for any commercial or non-commercial purpose.
See cstar.h or cstar.c for a DISCLAIMER OF WARRANTIES.
*/
#include "cstar.h"
/*
Externally visible routines:
*/
struct st_node * ast_lookup (char * symbol);
struct st_node * gst_enter (char * symbol,
struct type_node * type, int class);
static int gst_hash (char * symbol);
struct st_node * gst_lookup (char * symbol);
struct st_node * lst_enter (char * symbol,
struct type_node * type, int class);
static int lst_hash (char * symbol);
void lst_init (void);
struct st_node * lst_lookup (char * symbol);
struct st_node * rst_lookup (char * symbol);
struct st_node * rst_enter (char * symbol,
struct type_node * type, int class);
void st_init (void);
struct st_node * st_lookup (char * symbol);
/*
Internal routines:
*/
static void st_show (struct st_node * st_ht[], int size);
static void st_dump (void);
/*
Define the hash tables.
*/
#define G_PRIME 101
#define L_PRIME 101
static struct st_node * gst_ht [G_PRIME];
static struct st_node * lst_ht [L_PRIME];
/*
Dump all symbols of both symbol tables.
This function is used for debugging only.
*/
#ifdef SHERLOCK
static void
st_dump(void)
{
TRACEP("st_dump",
printf("&gst_ht=%p, &lst_ht=%p, ", gst_ht,lst_ht);
printf("*gst_ht=%p, *lst_ht=%p\n", *gst_ht, *lst_ht));
printf(">> Global symbols:\n");
st_show(gst_ht, G_PRIME);
printf("\n>> Local symbols:\n");
st_show(lst_ht, L_PRIME);
printf("\n");
}
static void
st_show(struct st_node * st_ht[], int size)
{
register int i;
register struct st_node *bp;
for (i = 0; i < size; i++) {
bp = st_ht[i];
if (bp != NULL) {
TRACEP("st_dump",
printf("st_show: st_ht [%d] = %p\n", i, bp));
do {
TRACEP("st_dump",
printf("st_show: typenode %p, next %p\n",
bp -> st_type, bp -> st_next));
printf("%s/%s: ",bp -> st_name,bp -> st_alias);
pr_sclass(bp -> st_sclass);
printf(" ");
if (bp -> st_type != NULL) {
pr_type(bp -> st_type);
printf("\n");
}
else {
printf("type <NULL>\n");
}
} while (bp = bp -> st_next);
}
}
}
#endif /* SHERLOCK */
/*
Look up a symbol in the local symbol table.
If not found, try the global symbol table.
*/
struct st_node *
st_lookup(register char * symbol)
{
register struct st_node * p;
struct st_node * gst_lookup();
struct st_node * lst_lookup();
TRACEPB("st_lookup", printf("(%s)\n", symbol));
p = lst_lookup(symbol);
if (p != NULL) {
RETURN_PTR("st_lookup", p);
}
else {
RETURN_PTR("st_lookup", gst_lookup(symbol));
}
}
/*
Look up a symbol in any symbol tables are appropriate to
scope.s_scope.
*/
struct st_node *
ast_lookup(symbol)
register char * symbol;
{
register struct st_node * p;
struct st_node * gst_lookup();
struct st_node * lst_lookup();
TRACEPB("ast_lookup", printf("(%s)\n", symbol));
switch(scope.s_scope) {
case PROTO_SCOPE:
case BLOCK_SCOPE:
/* try the block symbol table ... */
/*
if (p != NULL) {
break;
}
*/
/* FALL_THROUGH */
case FNDEF_SCOPE:
p = lst_lookup(symbol);
if (p != NULL) {
break;
}
/* FALL_THROUGH */
case FILE_SCOPE:
p = gst_lookup(symbol);
break;
default:
p = NULL;
t_error("ast_lookup: unknown scope");
}
RETURN_PTR("ast_lookup", p);
}
/*
Restricted lookup:
Look up a symbol in the symbol table local to scope.s_scope
It happens that this process will find the formals from the block
scope, although this may not be correct.
*/
struct st_node *
rst_lookup(symbol)
register char * symbol;
{
register struct st_node * p;
TRACEPB("rst_lookup", printf("(%s)\n", symbol));
switch(scope.s_scope) {
case PROTO_SCOPE:
case BLOCK_SCOPE:
case FNDEF_SCOPE:
RETURN_PTR("rst_lookup", lst_lookup(symbol));
case FILE_SCOPE:
RETURN_PTR("rst_lookup", gst_lookup(symbol));
default:
t_error("rst_lookup: unknown scope");
}
RETURN_PTR("rst_lookup", NULL);
}
/*
Place a symbol in whatever table is appropriate for
scope.s_scope.
*/
struct st_node *
rst_enter (symbol, type, class)
register char * symbol;
struct type_node * type;
int class;
{
TRACEPB("rst_enter", printf("(%s, %p, %d)\n",
symbol, type, class));
switch(scope.s_scope) {
case PROTO_SCOPE:
case BLOCK_SCOPE:
case FNDEF_SCOPE:
RETURN_PTR("rst_enter", lst_enter(symbol, type, class));
case FILE_SCOPE:
RETURN_PTR("rst_enter", gst_enter(symbol, type, class));
default:
t_error("rst_enter: unknown scope");
}
RETURN_PTR("rst_enter", NULL);
}
/*
Place a symbol in the global symbol table.
Return a pointer to the created node.
NOTE: gst_enter ought to be combined with lst_enter,
which would make things more orderly and make it easier to
adopt ANSI symbol tables.
*/
struct st_node *
gst_enter (register char * symbol, struct type_node * type, int class)
{
register struct st_node **bp0, *bp1;
TRACEPB("gst_enter", printf("(%s, %p, %d)\n",
symbol, type, class));
if (symbol == NULL) {
t_error("gst_enter: internal: NULL symbol");
symbol = "";
}
/* Dynamically allocate space for node. */
bp1 = CAST(struct st_node *) mg_alloc(sizeof(struct st_node));
/* Hang node from hash table. */
bp0 = &gst_ht[0];
bp0 += gst_hash(symbol);
bp1 -> st_next = *bp0;
*bp0 = bp1;
/* Fill in the name, type, and class fields. */
bp1 -> st_alias = str_gcat("_", symbol);
bp1 -> st_name = bp1 -> st_alias + 1;
bp1 -> st_type = type;
bp1 -> st_sclass = class;
RETURN_PTR("gst_enter", bp1);
}
/*
Place a symbol in the local symbol table.
Return a pointer to the created node.
*/
struct st_node *
lst_enter (register char * symbol, struct type_node * type, int class)
{
register struct st_node **bp0, *bp1;
TRACEPB("lst_enter", printf("(%s, %p, %d)\n",
symbol, type, class));
if (symbol == NULL) {
t_error("lst_enter: internal: NULL symbol");
symbol = "";
}
/* Dynamically allocate space for node. */
bp1 = CAST(struct st_node *) ml_alloc(sizeof(struct st_node));
/* Hang node from hash table. */
bp0 = &lst_ht[0];
bp0 += lst_hash(symbol);
bp1 -> st_next = *bp0;
*bp0 = bp1;
/* Fill in the name and text fields. */
bp1 -> st_alias = str_lcat("_", symbol);
bp1 -> st_name = bp1 -> st_alias + 1;
bp1 -> st_type = type;
bp1 -> st_sclass = class;
RETURN_PTR("lst_enter", bp1);
}
/*
Compute the hash function for a global symbol.
*/
static int
gst_hash (register char * symbol)
{
register int hash;
SL_DISABLE();
for (hash = 0; *symbol; ) {
hash *= 3;
hash += (int) *symbol++;
hash %= G_PRIME;
}
return hash;
}
/*
Compute the hash function for a local symbol.
*/
static int
lst_hash (register char * symbol)
{
register int hash;
SL_DISABLE();
for (hash = 0; *symbol; ) {
hash *= 3;
hash += (int) *symbol++;
hash %= L_PRIME;
}
return hash;
}
/*
Initialize both symbol tables.
*/
void
st_init(void)
{
register int i;
register struct st_node ** bp0;
TICKB("st_init");
/* Clear the global hash table. */
for (i = 0, bp0 = &gst_ht[0]; i < G_PRIME; i++) {
*bp0++ = NULL;
}
/* Clear the local hash table. */
lst_init();
TICKX("st_init");
}
/*
Re-initialize the local symbol table.
*/
void
lst_init(void)
{
register int i;
register struct st_node ** bp0;
/* Clear the local hash table. */
TICKB("lst_init");
for (i = 0, bp0 = &lst_ht[0]; i < L_PRIME; i++) {
*bp0++ = NULL;
}
TICKX("lst_init");
}
/*
Look up a symbol in the global symbol table.
Return a pointer to the node or NULL.
*/
struct st_node *
gst_lookup (register char * symbol)
{
register struct st_node ** bp0, *bp1;
/* Calculate the hash value of the symbol. */
TRACEPB("gst_lookup", printf("(%s)\n", symbol));
bp0 = &gst_ht[0];
bp0 += gst_hash(symbol);
/* Search down the list of gst_nodes. */
for (bp1 = *bp0; bp1; bp1 = bp1 -> st_next) {
if(str_eq(symbol, bp1 -> st_name)) {
/* Found. */
RETURN_PTR("gst_lookup", bp1);
}
}
/* Return failure. */
RETURN_PTR("gst_lookup", NULL);
}
/*
Look up a symbol in the local symbol table.
Return a pointer to the node or NULL.
*/
struct st_node *
lst_lookup (register char * symbol)
{
register struct st_node ** bp0, *bp1;
/* Calculate the hash value of the symbol. */
TRACEPB("lst_lookup", printf("(%s)\n", symbol));
bp0 = &lst_ht[0];
bp0 += lst_hash(symbol);
/* Search down the list of lst_nodes. */
for (bp1 = *bp0; bp1; bp1 = bp1 -> st_next) {
if(str_eq(symbol, bp1 -> st_name)) {
/* Found. */
RETURN_PTR("lst_lookup", bp1);
}
}
/* Return failure. */
RETURN_PTR("lst_lookup", NULL);
}